# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: jhkim, inkyu

import logging

from coin.exchange.okex_futures.kr_rest.currency import OkexCurrency
from coin.exchange.okex_futures.kr_rest.futures_product import OkexFuturesProduct
from coin.strategy.mm.okex_futures.order_subsystem import (OkexFuturesOrderSubsystem,
                                                           OkexFuturesOrderSubsystemV3)
from coin.strategy.mm.okex_futures_swap.order_subsystem import (OkexFuturesSwapOrderSubsystem)
from coin.strategy.mm.base.unary_multifeed_strategy_base import UnaryMultifeedStrategyBase
from coin.strategy.mm.base.bitmex_strategy_base import (BitmexPositionBalancePrinter,
                                                        calculate_unrealized_pnl)
from coin.strategy.mm.subscription import SubscriptionRequest


class OkexFuturesPositionBalancePrinter(BitmexPositionBalancePrinter):
  def __init__(self, currency, products, bookmap, logger=None):
    super().__init__(products,
                     bookmap,
                     currency=currency,
                     logger=(logger or logging.getLogger('OkexFuturesPositionBalancePrinter')))

  def _get_pos(self, product):
    book = self._bookmap.get_book(product)
    if book is None or not book.has_ask() or not book.has_bid():
      return None, None

    pos = self._og.get_okex_futures_position(product)
    if product.base.currency == 'BTC':
      pos_multiplier = 100.
    else:
      pos_multiplier = 10.

    long_pos = pos.long * pos_multiplier
    long_unrealized_pnl = calculate_unrealized_pnl(product,
                                                   long_pos,
                                                   pos.long_avg_price,
                                                   book.ask0().price,
                                                   book.bid0().price)

    short_pos = -pos.short * pos_multiplier
    short_unrealized_pnl = calculate_unrealized_pnl(product,
                                                    short_pos,
                                                    pos.short_avg_price,
                                                    book.ask0().price,
                                                    book.bid0().price)

    net_pos = long_pos + short_pos
    net_unrealized_pnl = long_unrealized_pnl + short_unrealized_pnl
    return net_pos, net_unrealized_pnl


class OkexFuturesStrategyBase(UnaryMultifeedStrategyBase):
  CurrencyType = OkexCurrency
  ProductType = OkexFuturesProduct
  LiveEnvironmentType = OkexFuturesOrderSubsystem
  OGName = SubscriptionRequest('Futures', 'Okex', 'v1')


class OkexFuturesStrategyBaseV3(UnaryMultifeedStrategyBase):
  CurrencyType = OkexCurrency
  ProductType = OkexFuturesProduct
  LiveEnvironmentType = OkexFuturesOrderSubsystemV3
  OGName = SubscriptionRequest('Futures', 'Okex', 'v3')


class OkexSwapStrategyBase(UnaryMultifeedStrategyBase):
  CurrencyType = OkexCurrency
  ProductType = OkexFuturesProduct
  LiveEnvironmentType = OkexFuturesSwapOrderSubsystem
  OGName = SubscriptionRequest('Futures', 'Okex', 'v3_swap')
